﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
using System.Globalization;

namespace DDNY.WebPortals.Common
{
    public class FeedPersister
    {
        public const string dateFormatForFiles = "yyyy_MM_dd_HH";
        public const string dateFormatForWeb = "yyyy-MM-dd-HH";
        public static CultureInfo provider
        {
            get
            {
                return CultureInfo.InvariantCulture;
            }
        }

        public static List<RssItem> GetItemsForFeedByDateAndTime(string feedUrl, DateTime time, int maxNumber, bool trimContent, bool hideContent)
        {
            List<RssItem> result = new List<RssItem>();
            XmlDocument doc = new XmlDocument();
            string xmlPath;
            xmlPath = GetFilePathForFeed(feedUrl, time);

            doc.Load(xmlPath);
            foreach (XmlNode nodeItem in doc.SelectNodes("/rss/channel/item"))
            {
                RssItem itemToAdd = new RssItem();
                if (hideContent == false)
                {
                    itemToAdd.Content = nodeItem.SelectSingleNode("description").InnerText;
                    if (trimContent == true)
                    {
                        itemToAdd.Content = TrimContent(itemToAdd.Content, 80);
                    }
                }

                itemToAdd.LinkUrl = nodeItem.SelectSingleNode("link").InnerText;
                itemToAdd.Title = nodeItem.SelectSingleNode("title").InnerText;
                bool itemIsFine = CheckItemForBadWords(itemToAdd);
                if (itemIsFine)
                {
                    result.Add(itemToAdd);
                }

                if (result.Count == maxNumber)
                {
                    break;
                }
            }
            return result;
        }

        private static bool CheckItemForBadWords(RssItem itemToAdd)
        {
            bool result = true;
            //TODO
            return result;
        }

        private static string TrimContent(string input, int maxLength)
        {
            string temp = input;
            if (temp.Length < maxLength)
            {
                maxLength = temp.Length;
            }
            temp = temp.Substring(0, maxLength);
            maxLength = temp.LastIndexOf(' ');
            string result;
            if (maxLength == -1)
            {
                result = temp;
            }
            else
            {
                result = temp.Substring(0, maxLength);
            }

            return result;
        }

        public static string GetFilePathForFeed(string feedUrl, DateTime time)
        {
            try
            {
                Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
                string folderName = xmlsFolder;
                string datePart = time.ToString(dateFormatForFiles);
                string xmlFileName = feedUrl.GetHashCode().ToString() + "_" + datePart + ".xml";
                string fullPath = Path.Combine(folderName, xmlFileName);
                if (!Directory.Exists(folderName))
                {
                    Directory.CreateDirectory(folderName);
                }
                if (!File.Exists(fullPath))
                {
                    XmlDocument doc = new XmlDocument();
                    feedUrl = feedUrl.Replace("&amp;", "&");
                    doc.Load(feedUrl);
                    bool hasNewContent = false;

                    DateTime lastPostDate = getLastPostDateFromFeedXmlDocument(doc);

                    if (lastPostDate.Date == time.Date)
                    {
                        hasNewContent = true;
                    }
                    else
                    {
                        string lastPostDatePart = lastPostDate.ToString(dateFormatForFiles);
                        fullPath = fullPath.Replace(datePart, lastPostDatePart);
                    }
                    if (hasNewContent)
                    {
                        doc.Save(fullPath);
                    }
                    else
                    {
                        if (!File.Exists(fullPath))
                        {
                            doc.Save(fullPath);
                        }
                    }

                }
                return fullPath;
            }
            catch (Exception)
            {

                throw;
            }

        }

        private static DateTime getLastPostDateFromFeedXmlDocument(XmlDocument doc)
        {
            DateTime result = DateTime.MinValue;
            foreach (XmlNode nodeItem in doc.SelectNodes("/rss/channel/item"))
            {
                string pubDate = nodeItem.SelectSingleNode("pubDate").InnerText;
                DateTime buffer = DateTime.MinValue;
                bool parsed = Rfc822DateTime.TryParse(pubDate, out buffer);
                if (buffer.CompareTo(result) > 0)
                {
                    result = buffer;
                }
            }


            return result;

        }

        public static List<DateTime> GetDatesPersistedForFeed(string feedUrl)
        {
            List<DateTime> dates = new List<DateTime>();
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

            string folderName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, xmlsFolder);
            string[] files = Directory.GetFiles(folderName, feedUrl.GetHashCode().ToString() + "*.xml");
            foreach (string fullFilePath in files)
            {
                string file = Path.GetFileName(fullFilePath);
                DateTime dateToAdd = GetDateFromFileName(file);
                dates.Add(dateToAdd);
            }
            return dates;
        }



        private static DateTime GetDateFromFileName(string file)
        {
            int startIndex = file.IndexOf("_");
            int endIndex = file.IndexOf(".");
            string dateTimeString = file.Substring(startIndex + 1, endIndex - startIndex - 1);
            return DateTime.ParseExact(dateTimeString, dateFormatForFiles, provider);
        }





        public static int NthIndexOf(string target, string value, int n)
        {
            Match m = Regex.Match(target, "((" + value + ").*?){" + n + "}");

            if (m.Success)
                return m.Groups[2].Captures[n - 1].Index;
            else
                return -1;
        }


        const string xmlsFolder = "xmls";

    }
}
